﻿using System.Windows;
using System.Windows.Controls.Primitives;
using System.Windows.Controls;
using System.Windows.Input;

namespace Monti.Docking
{
   /// <summary>
   /// Content used for a dock site.
   /// </summary>
   [TemplatePart (Name = "PART_CloseButton", Type = typeof (ButtonBase))]
   internal class DockContent : TabItem
   {
      #region Setup

      /// <summary>
      /// Static constructor.
      /// </summary>
      static DockContent ()
      {
         DefaultStyleKeyProperty.OverrideMetadata(typeof(DockContent),
            new FrameworkPropertyMetadata(typeof(DockContent)));
      }

      /// <summary>
      /// Initializes a new dock content object.
      /// </summary>
      public DockContent ()
      {
         this.PreviewMouseDown += DockContentPreviewMouseDown;
      }

      #endregion

      #region Properties

      /// <summary>
      /// Gets or Sets the icon for the tab. This is a dependency property.
      /// </summary>
      public object Icon
      {
         get { return GetValue (IconProperty); }
         set { SetValue(IconProperty, value); }
      }

      /// <summary>
      /// Dependency property for dock content's icon.
      /// </summary>
      public static readonly DependencyProperty IconProperty =
         DependencyProperty.Register ("Icon", typeof (object), typeof (DockContent), new UIPropertyMetadata (null));

      /// <summary>
      /// Gets or Sets the dock content's ability to close. This is a dependency property.
      /// </summary>
      public bool AllowClose
      {
         get { return (bool)GetValue(AllowCloseProperty); }
         set { SetValue(AllowCloseProperty, value); }
      }

      /// <summary>
      /// Dependency property for dock content's ability to close.
      /// </summary>
      public static readonly DependencyProperty AllowCloseProperty =
         DependencyProperty.Register ("AllowClose", typeof (bool), typeof (DockContent), 
         new UIPropertyMetadata (true));

      /// <summary>
      /// Gets or Sets if this is the active content for the dock manager.
      /// </summary>
      public bool IsActiveContent
      {
         get { return (bool)GetValue (IsActiveContentProperty); }
         set { SetValue (IsActiveContentProperty, value); }
      }

      /// <summary>
      /// Dependency property for if this is the active content for the dock manager.
      /// </summary>
      public static readonly DependencyProperty IsActiveContentProperty =
         DependencyProperty.Register ("IsActiveContent", typeof (bool), typeof (DockContent), 
         new UIPropertyMetadata (false));

      /// <summary>
      /// Gets the owner dock site.
      /// </summary>
      internal DockSite DockSite { get; set; }

      #endregion

      #region Methods

      /// <summary>
      /// Occurs when the user clicks this dock content (or the content).
      /// </summary>
      /// <param name="sender">Object that raised the event.</param>
      /// <param name="e">MouseButtonEventArgs</param>
      void DockContentPreviewMouseDown (object sender, MouseButtonEventArgs e)
      {
         if (e.ChangedButton == MouseButton.Middle && this.AllowClose)
            this.DockSite.RemoveContent (this.DataContext);
      }

      /// <summary>
      /// Occurs when the content is selected.
      /// </summary>
      /// <param name="e">RoutedEventArgs</param>
      protected override void OnSelected (RoutedEventArgs e)
      {
         this.SetAsActiveContent ();
         base.OnSelected (e);
      }
      
      /// <summary>
      /// Occurs when the content is unselected.
      /// </summary>
      /// <param name="e">RoutedEventArgs</param>
      protected override void OnUnselected(RoutedEventArgs e)
      {
         this.IsActiveContent = false;
         base.OnUnselected(e);
      }

      /// <summary>
      /// Notifies the dockmanager of the change in active content.
      /// </summary>
      internal void SetAsActiveContent ()
      {
         if (this.IsActiveContent && this.DockSite.DockMan.ActiveContent == this.DataContext) return;
         this.IsActiveContent = true;
         this.DockSite.DockMan.FireActiveContentChanged (this);
      }

      #endregion
   }
}
